#ifndef __THREADPOOL_H
#define __THREADPOOL_H

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <errno.h>
#include <error.h>
#include <sys/mman.h>
#include <sys/wait.h>
#include <time.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <signal.h>
#include <dirent.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/epoll.h>
#include <assert.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <pthread.h>
#include <sys/uio.h>
#include <sys/sendfile.h>
#include <sys/stat.h>  // for stat

#define SIZE(a) (sizeof(a)/sizeof(a[0]))

typedef void (*sighandler_t)(int);

#define ARGS_CHECK(argc, num)   {\
    if(argc != num){\
        fprintf(stderr, "ARGS ERROR!\n");\
        return -1;\
    }}

#define ERROR_CHECK(ret, num, msg) {\
    if(ret == num) {\
        perror(msg);\
        return -1;\
    }}

#define THREAD_ERROR_CHECK(ret, func) {\
    if(ret != 0) {\
        fprintf(stderr, "%s:%s\n", func, strerror(ret));\
    }}
// 登录状态
typedef enum {
    LOGIN_OFF = 0,
    LOGIN_IN
}login_status_t;

// 用户信息结构体
typedef struct {
    int net_fd;
    login_status_t login_status;
    char name[20];
    char encrypted[255];
    char pwd[128];
}user_info_t;

// w--get_setting
// 根据pwdp（密文）的格式提取出seeting值（也就是盐值）
void get_setting(char *setting, char *cipher_text);

// w--服务端验证
void verify(int fd, int *login_flag);// 后面这一步将分成下面两步

// 登录验证阶段一，得到用户的用户名
void login_step_one(user_info_t *user);

// 登录验证阶段二，得到用户的密文，并比对
void login_step_two(user_info_t *user);

void register_step_one(user_info_t *user);

void register_step_two(user_info_t *user);


typedef enum {
    CMD_TYPE_PWD=1,
    CMD_TYPE_LS,
    CMD_TYPE_CD,
    CMD_TYPE_MKDIR,
    CMD_TYPE_RMDIR,
    CMD_TYPE_PUTS,
    CMD_TYPE_GETS,
    CMD_TYPE_NOTCMD,  //不是命令

    // 用于登录和注册
    LOGIN_STEP_ONE = 666,
    LOGIN_STEP_ONE_OK,
    LOGIN_STEP_ONE_ERR,
    LOGIN_STEP_TWO,
    LOGIN_STEP_TWO_OK,
    LOGIN_STEP_TWO_ERR,

    REGISTER_STEP_ONE,
    REGISTER_STEP_ONE_OK,
    REGISTER_STEP_ONE_ERR,
    REGISTER_STEP_TWO,
    REGISTER_STEP_TWO_OK,
    REGISTER_STEP_TWO_ERR

}CmdType;

typedef struct 
{
    int len;//记录内容长度
    CmdType type;
    char buff[1000];//记录内容本身
}train_t;

typedef struct task_s{
    int peerfd;
    int epfd;
    CmdType type;
    char data[1000];
    user_info_t* user; // add by sjk 2024.6.20 在task里面加入用户信息,方便处理命令
    struct task_s * pNext;
}task_t;

typedef struct task_queue_s
{
    task_t * pFront;
    task_t * pRear;
    int queSize;//记录当前任务的数量
    pthread_mutex_t mutex; 
    pthread_cond_t cond;
    int flag;//0 表示要退出，1 表示不退出

}task_queue_t;

typedef struct threadpool_s {
    pthread_t * pthreads;
    int pthreadNum;
    task_queue_t que;//...任务队列
}threadpool_t;

int queueInit(task_queue_t * que);
int queueDestroy(task_queue_t * que);
int queueIsEmpty(task_queue_t * que);
int taskSize(task_queue_t * que);
int taskEnque(task_queue_t * que, task_t * task);
task_t * taskDeque(task_queue_t * que);
int broadcastALL(task_queue_t* que);

int threadpoolInit(threadpool_t *, int num);
int threadpoolDestroy(threadpool_t *);
int threadpoolStart(threadpool_t *);
int threadpoolStop(threadpool_t *);


int tcpInit(const char * ip, const char * port);
int addEpollReadfd(int epfd, int fd);
int delEpollReadfd(int epfd, int fd);
int transferFile(int sockfd);

//6.16 Fmy
void transferTaskData(task_t *task);
//6.16 Fmy end

int sendn(int sockfd, const void * buff, int len);
int recvn(int sockfd, void * buff, int len);

//处理客户端发过来的消息
void handleMessage(int sockfd, int epfd, task_queue_t * que);

//执行任务的总的函数
void doTask(task_t * task);
//每一个具体命令的执行
void cdCommand(task_t * task);
void lsCommand(task_t * task);
void pwdCommand(task_t * task);
void mkdirCommand(task_t * task);
void rmdirCommand(task_t * task);
void notCommand(task_t * task);
void putsCommand(task_t * task);
void getsCommand(task_t * task);

// wmx-6.19
void userLoginCheckOne(task_t * task);
void userLoginCheckTwo(task_t * task);
void userRegisterOne(task_t * task);
void userRegisterTwo(task_t * task);
user_info_t *return_user(task_t *task);

// 结果集结构体定义
typedef struct {
    char ***rows;   // 二维字符数组，存储每行每列的数据
    int num_rows;   // 结果集行数
    int num_cols;   // 结果集列数
} QueryResult;


#endif

